package com.grm.runner;

import io.netty.bootstrap.ServerBootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;

/**
 * Netty 服务器运行器
 * 该类实现了 CommandLineRunner 接口，允许在 Spring Boot 应用程序启动后执行特定的操作
 * 主要负责在应用程序启动后启动 Netty 服务器
 */
@Component
public class NettyServerRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(NettyServerRunner.class);

    // ServerBootstrap 是 Netty 提供的用于启动服务器的辅助类
    private final ServerBootstrap serverBootstrap;

    // 从配置文件中读取端口号
    @Value("${netty.port}")
    private int port;

    /**
     * 构造函数，注入 ServerBootstrap 实例
     * @param serverBootstrap ServerBootstrap 实例，用于配置和启动 Netty 服务器
     */
    public NettyServerRunner(ServerBootstrap serverBootstrap) {
        this.serverBootstrap = serverBootstrap;
    }

    /**
     * 实现 CommandLineRunner 接口的 run 方法
     * 该方法将在 Spring Boot 应用程序启动后调用，用于启动 Netty 服务器
     * @param args 命令行参数，通常未使用
     */
    @Override
    public void run(String... args) {
        CompletableFuture.runAsync(() -> {
            try {
                // 启动 Netty 服务器，并监听指定端口
                var channelFuture = serverBootstrap.bind(port).sync();
                logger.info("Netty server started successfully on port {}", port);
                channelFuture.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                logger.error("Netty server startup was interrupted", e);
                throw new RuntimeException("Netty server startup was interrupted", e);
            } catch (Exception e) {
                logger.error("Netty server failed to start on port {}", port, e);
                throw new RuntimeException("Netty server failed to start", e);
            }
        }).exceptionally(throwable -> {
            logger.error("Netty server startup encountered an exception", throwable);
            throw new RuntimeException("Netty server startup encountered an exception", throwable);
        });
    }
}
